home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.12 Dec 89 / AACK Folder / main.p < prev    next >
Encoding:
Text File  |  1989-03-30  |  23.4 KB  |  1,066 lines  |  [TEXT/PJMM]

  1. program AACK;
  2.  
  3.  
  4.     uses
  5.         AppleTalk, Globals, LowLevelATProcs, Hooks;
  6.  
  7.  
  8.     procedure Crash;
  9.     {This proc is called if we crash}
  10.     begin
  11.         ExitToShell;
  12.     end;
  13.  
  14.  
  15.     procedure SetUpToolbox;
  16.     {This proc inits the Mac toolbox}
  17.     begin
  18.         MaxApplZone;
  19.         MoreMasters;
  20.         MoreMasters;
  21.         MoreMasters;
  22.         MoreMasters;
  23.         InitGraf(@thePort);
  24.         InitFonts;
  25.         InitWindows;
  26.         FlushEvents(everyEvent, 0);
  27.         InitMenus;
  28.         TEInit;
  29.         InitDialogs(@Crash);
  30.         InitCursor;
  31.     end;
  32.  
  33.  
  34.     procedure SetUpGlobals;
  35.     {This proc does any app global inits}
  36.     begin
  37.         DoneFlag := F;
  38.  
  39.         DragRect := screenBits.bounds;
  40.         with DragRect do
  41.             begin
  42.                 top := top + 20;    {NOTE! we really should use the mbarheight}
  43.                 left := left + 4;
  44.                 bottom := bottom - 4;
  45.                 right := right - 4;
  46.             end;
  47.  
  48.     {Assume the new calls dont exist}
  49.         NewCallsExist := F;
  50.  
  51.         SleepTime := 10;
  52.  
  53. {$IFC TALK_DEBUG }
  54.         with DebugOnRect do
  55.             begin
  56.                 top := 0;
  57.                 left := 0;
  58.                 bottom := 4;
  59.                 right := 4;
  60.             end;
  61.  
  62.         with SelfSendOnRect do
  63.             begin
  64.                 top := 5;
  65.                 left := 0;
  66.                 bottom := 9;
  67.                 right := 4;
  68.             end;
  69.  
  70. {$ENDC}
  71.  
  72.     {Allow setup of any globals from the Hooks unit}
  73.         SetUpHooksGlobals;
  74.     end;
  75.  
  76.  
  77.     procedure SetUpMenus;
  78.     {This proc sets upthe generic codes menus}
  79.     begin
  80.         AppleMenu := GetMenu(APPLEMENUID);
  81.         AddResMenu(AppleMenu, 'DRVR');
  82.         InsertMenu(AppleMenu, 0);
  83.  
  84.         FileMenu := GetMenu(FILEMENUID);
  85.         InsertMenu(FileMenu, 0);
  86.  
  87.         EditMenu := GetMenu(EDITMENUID);
  88.         InsertMenu(EditMenu, 0);
  89.  
  90.         SpecialMenu := GetMenu(SPECIALMENUID);
  91.         InsertMenu(SpecialMenu, 0);
  92.  
  93.     {Allow setup of any menus from the Hooks unit}
  94.         SetUpHooksMenus;
  95.  
  96.         DrawMenuBar;
  97.     end;
  98.  
  99.  
  100.     procedure CloseWindows;
  101.     {This proc closes the apps windows}
  102.     begin
  103.     {Allow closing of any windows from the Hooks unit}
  104.         CloseHooksWindows;
  105.  
  106.         if UserWindowProcsChanged then
  107.             HooksCloseUserWindowProc {Let the hook code do it magic}
  108.         else
  109.             begin
  110.                 LDispose(NameListHdl);
  111.                 CloseWindow(UserWindow);
  112.             end;
  113.     end;
  114.  
  115.  
  116.     function GotWindows: Boolean;
  117.     {This code sets up the apps windows, it returns T}
  118.     {if it succeeds}
  119.         var
  120.             theCell: Cell;
  121.             dBounds: Rect;
  122.     begin
  123.     {Assume we fail}
  124.         GotWindows := F;
  125.  
  126.         UserWindowRect := DragRect;
  127.         with UserWindowRect do
  128.             begin
  129.                 top := top + 20;
  130.                 left := left + 4;
  131.                 bottom := top + 200;
  132.                 right := left + 225;
  133.             end;
  134.  
  135.     {Get the UserWindow}
  136.         UserWindow := NewWindow(@UserWRec, UserWindowRect, UserNTT.objStr, F, noGrowDocProc, WindowPtr(-1), T, 0);
  137.         if UserWIndow <> nil then
  138.             begin
  139.                 SetPort(UserWindow);
  140.                 ClipRect(UserWindow^.portRect);
  141.                 TextFont(monaco);
  142.                 TextSize(9);
  143.  
  144.                 GetFontInfo(UserWindowFontInfo);
  145.                 with UserWindowFontInfo do
  146.                     TextHeight := ascent + descent + leading;
  147.  
  148.     {Set the # of rows to display in our list}
  149.                 MaxRows := 10;
  150.  
  151.     {Set the current list length to 0}
  152.                 NameListLength := 0;
  153.  
  154.                 with dBounds do
  155.                     begin
  156.                         top := 0;
  157.                         left := 0;
  158.                         bottom := NameListLength; {no rows for now}
  159.                         right := 1; {one column}
  160.                     end;
  161.  
  162.                 theCell.h := 0;
  163.                 theCell.v := 0;
  164.  
  165.     {Set up the lists view rect}
  166.                 with ListViewRect do
  167.                     begin
  168.                         top := 10;
  169.                         left := 10;
  170.                         bottom := (TextHeight * MaxRows) + ListViewRect.top;
  171.                         right := (32 * CharWidth('w')) + 8;
  172.                     end;
  173.  
  174.     {Try to get a ListHandle}
  175.                 NameListHdl := LNew(ListViewRect, dBounds, theCell, 0, UserWindow, T, F, F, T);
  176.  
  177.                 if NameListHdl = nil then
  178.         {We failed to get a ListHandle so close the UserWindow and exit}
  179.                     CloseWindow(UserWindow)
  180.                 else
  181.                     begin
  182.         {We got the ListHandle, allow only one selection at a time from it}
  183.                         NameListHdl^^.selFlags := LOnlyOne;
  184.  
  185.         {Set up a rect to put a frame around our list}
  186.                         ListFrameRect := ListViewRect;
  187.                         with ListFrameRect do
  188.                             begin
  189.                                 top := top - 1;
  190.                                 left := left - 1;
  191.                                 bottom := bottom + 1;
  192.                                 right := right + 16;
  193.  
  194.         {Set up the pos to draw the LookUpName results at}
  195.                                 with LookUpStringPos do
  196.                                     begin
  197.                                         h := left;
  198.                                         v := bottom + TextHeight;
  199.                                     end;
  200.  
  201.         {Set up the pos to draw the ConfirmName results at}
  202.                                 with ConfirmStringPos do
  203.                                     begin
  204.                                         h := left;
  205.                                         v := LookUpStringPos.v + TextHeight;
  206.                                     end;
  207.  
  208.                             end;
  209.  
  210.         {Set up the rect to erase the old LookUpName result}
  211.                         with LookUpStringRect do
  212.                             begin
  213.                                 top := ListFrameRect.bottom + 1;
  214.                                 left := UserWindow^.portRect.left;
  215.                                 bottom := LookUpStringPos.v + UserWindowFontInfo.descent;
  216.                                 right := UserWindow^.portRect.right;
  217.                             end;
  218.  
  219.         {Set up the rect to erase the old ConfirmName result}
  220.                         with ConfirmStringRect do
  221.                             begin
  222.                                 top := LookUpStringRect.bottom + 1;
  223.                                 left := UserWindow^.portRect.left;
  224.                                 bottom := ConfirmStringPos.v + UserWindowFontInfo.descent;
  225.                                 right := UserWindow^.portRect.right;
  226.                             end;
  227.  
  228.         {Set to false, assume no hook code override}
  229.                         UserWindowProcsChanged := F;
  230.  
  231.     {Allow setup of any windows from the Hooks unit}
  232.                         if SetUpHooksWindows = T then
  233.                             begin
  234.                                 ShowWindow(UserWindow);
  235.         {We succeeded!  Return T}
  236.                                 GotWindows := T;
  237.                             end
  238.                         else
  239.                             begin
  240.         {SetUpHooksWindows failed}
  241.                                 LDispose(NameListHdl);
  242.                                 CloseWindow(UserWindow);
  243.                             end;
  244.                     end;
  245.             end;
  246.     end;
  247.  
  248.  
  249.     procedure DoDrag;
  250.     {This code drags windows around}
  251.     begin
  252.         DragWindow(WhichWindow, Evt.where, DragRect);
  253.     end;
  254.  
  255.  
  256.     procedure ActivateUserWindow;
  257.     {This code activates the apps windows}
  258.     begin
  259.         if UserWindowProcsChanged then
  260.             HooksActivateUserWindowProc {Let the hook code do its magic}
  261.         else
  262.             LActivate(T, NameListHdl);
  263.     end;
  264.  
  265.  
  266.     procedure DeactivateUserWindow;
  267.     {This code deactivates the apps windows}
  268.     begin
  269.         if UserWindowProcsChanged then
  270.             HooksDeactivateUserWindowProc {Let the hook code do its magic}
  271.         else
  272.             LActivate(F, NameListHdl);
  273.     end;
  274.  
  275.  
  276.     procedure UpdateNameList;
  277.     {This code updates the list of names in the NameListHandle}
  278.         var
  279.             theAddress: AddrBlock;
  280.             theCell: Cell;
  281.             theNTT: EntityName;
  282.             theNum: Integer;
  283.             err: OSErr;
  284.             thePtr: Ptr;
  285.     begin
  286.         with LookUpNamePb do
  287.             begin
  288.                 if NameListLength <> 0 then
  289.                     LDelRow(NameListLength, 0, NameListHdl); {Delete any rows present}
  290.                 NameListLength := xMPPPb.numGotten; {Get the new # of rows needed}
  291.                 if NameListLength <> 0 then
  292.                     begin
  293.                         theNum := LAddRow(NameListLength, 0, NameListHdl); {Add the # of new rows}
  294.                         theCell.h := 0;
  295.                         for theNum := 1 to NameListLength do
  296.                             begin
  297.                                 err := NBPExtract(@LookUpBuffer, NameListLength, theNum, theNTT, theAddress); {extract a name}
  298.                                 if err = noErr then
  299.                                     begin
  300.                                         theCell.v := theNum - 1; {Cells are numbered starting from zero so bump row # back}
  301.                                         thePtr := Ptr(ORD4(@theNTT.objStr) + 1); {Pt to the data}
  302.                                         LSetCell(thePtr, length(theNTT.objStr), theCell, NameListHdl); {Set the cells data}
  303.                                     end;
  304.                             end;
  305.         {Select the first row}
  306.                         theCell.h := 0;
  307.                         theCell.v := 0;
  308.                         LSetSelect(T, theCell, NameListHdl);
  309.                     end;
  310.             end;
  311.     end;
  312.  
  313.  
  314.     procedure UpdateUserWindow;
  315.     {This code updates the UserWindow}
  316.         var
  317.             theRgn: RgnHandle;
  318.     begin
  319.         if UserWindowProcsChanged then
  320.             HooksUpdateUserWindowProc {Let the hook code do its magic}
  321.         else
  322.             begin
  323. {$IFC TALK_DEBUG }
  324.                 ForeColor(redColor);
  325.                 FillRect(DebugOnRect, black);
  326.  
  327.                 if SelfSendOn then
  328.                     begin
  329.                         ForeColor(cyanColor);
  330.                         FillRect(SelfSendOnRect, black);
  331.                     end
  332.                 else
  333.                     begin
  334.                         ForeColor(cyanColor);
  335.                         FrameRect(SelfSendOnRect);
  336.                     end;
  337.  
  338.                 ForeColor(blackColor);
  339. {$ENDC}
  340.  
  341.                 FrameRect(ListFrameRect); {Put a frame around the list}
  342.                 theRgn := UserWindow^.visRgn;
  343.                 LUpdate(theRgn, NameListHdl); {Update the list}
  344.                 DrawLookUpString; {Draw in last LookUpName result}
  345.                 DrawConfirmString; {Draw in last ConfirmName result}
  346.             end;
  347.     end;
  348.  
  349.  
  350.     procedure DoActivate;
  351.     {This code activates any app windows}
  352.         var
  353.             theWindow: WindowPtr;
  354.     begin
  355.         theWindow := WindowPtr(Evt.message);
  356.         SetPort(theWindow);
  357.         if BAnd(activeFlag, Evt.modifiers) <> 0 then
  358.             begin
  359.                 if theWindow = UserWindow then
  360.                     ActivateUserWindow
  361.                 else
  362.                     ActivateHooksWindow(theWindow); {Let the hook code activate its windows}
  363.             end
  364.         else
  365.             begin
  366.                 if theWindow = UserWindow then
  367.                     DeactivateUserWindow
  368.                 else
  369.                     DeactivateHooksWindow(theWindow); {Let the hook code deactivate its windows}
  370.             end;
  371.     end;
  372.  
  373.  
  374.     procedure DoUpdate;
  375.     {This proc does updates of app windows}
  376.         var
  377.             oldPort: GrafPtr;
  378.             theWindow: WindowPtr;
  379.     begin
  380.         GetPort(oldPort);
  381.  
  382.         theWindow := WindowPtr(Evt.message);
  383.         SetPort(theWindow);
  384.  
  385.         BeginUpdate(theWindow);
  386.  
  387.         if theWindow = UserWindow then
  388.             UpdateUserWindow
  389.         else
  390.             UpdateHooksWindow(theWindow); {Let the hook code update any of its windows}
  391.  
  392.         EndUpdate(theWindow);
  393.  
  394.         SetPort(oldPort);
  395.     end;
  396.  
  397.  
  398.     procedure DoMFEvent;
  399.     {This code handles MultiFinder events such as deac/activation of}
  400.     {windows upon suspend/resume events}
  401.         var
  402.             theWindow: WindowPtr;
  403.     begin
  404.         theWindow := FrontWindow;
  405.         case BSR(Evt.message, 24) of    {high byte of message}
  406.             SUSPENDRESUMEMSG: 
  407.                 begin
  408.                     if BAnd(Evt.message, RESUMEMASK) <> 0 then
  409.                         begin
  410.                             SleepTime := 10;
  411.                             SetPort(theWindow);
  412.                             if theWindow = UserWindow then
  413.                                 ActivateUserWindow
  414.                             else
  415.                                 ActivateHooksWindow(theWindow); {Let the hook code activate its windows}
  416.                         end
  417.                     else
  418.                         begin
  419.                             SleepTime := 60;
  420.                             SetPort(theWindow);
  421.                             if theWindow = UserWindow then
  422.                                 DeactivateUserWindow
  423.                             else
  424.                                 DeactivateHooksWindow(theWindow); {Let the hook code deactivate its windows}
  425.                         end;
  426.                 end;
  427.             otherwise
  428.         end;
  429.     end;
  430.  
  431.  
  432.     function UserRegistered: Boolean;
  433.     {This proc lets the User register on the network, it return T}
  434.     {T if it succeeds}
  435.         label
  436.             100;
  437.         var
  438.             localATPPb: ATPParamBlock;
  439.             theDialog: DialogPtr;
  440.             theDRec: DialogRecord;
  441.             oldPort: GrafPtr;
  442.             item: Handle;
  443.             itemHit: Integer;
  444.             localMPPPb: MPPParamBlock;
  445.             err: OSErr;
  446.             itemRect: Rect;
  447.             theStr32Hdl: Str32Hdl;
  448.             theString: Str255;
  449.     begin
  450.     {Assume we fail}
  451.         UserRegistered := F;
  452.  
  453. {Get the string entered in the 'Chooser'}
  454.         theStr32Hdl := Str32Hdl(GetResource('STR ', rCHOOSERUSERSTRID));
  455.  
  456. {If there is no default user name from the chooser, then set theString to the}
  457. {null string}
  458.         if theStr32Hdl = nil then
  459.             theString := '';
  460.  
  461.         GetPort(oldPort);
  462.  
  463.         theDialog := GetNewDialog(rUSERNAMEDLOGID, @theDRec, WindowPtr(-1));
  464.         SetPort(theDialog);
  465.  
  466.         ShowWindow(theDialog);
  467.  
  468. 100:
  469.         if theStr32Hdl <> nil then
  470.             begin
  471.                 HLock(Handle(theStr32Hdl));
  472.                 theString := theStr32Hdl^^; {theString = the chooser string}
  473.                 HUnlock(Handle(theStr32Hdl));
  474.             end;
  475.  
  476.     {Show theString in the dialog and select it}
  477.         GetDItem(theDialog, rUSERNAMEITEM, itemHit, item, itemRect);
  478.         SetIText(item, theString);
  479.         SelIText(theDialog, rUSERNAMEITEM, 0, 32767);
  480.  
  481.     {Loop until OK or Cancel is hit}
  482.         repeat
  483.             ModalDialog(nil, itemHit)
  484.         until ((itemHit = ok) or (itemHit = cancel));
  485.  
  486.         if itemHit = ok then
  487.             begin
  488.                 GetDItem(theDialog, rUSERNAMEITEM, itemHit, item, itemRect);
  489.                 GetIText(item, theString);
  490.                 itemHit := length(theString);
  491.                 if (itemHit > 0) and (itemHit <= MAXNAMELENGTH) then
  492.                     begin
  493.         {theString must be > 0 but < 32}
  494.         {First try to open a socket}
  495.                         with localATPPb do
  496.                             begin
  497.                                 ioCompletion := nil;
  498.                                 atpSocket := 0;
  499.                                 with addrBlock do
  500.                                     begin
  501.                                         aNet := 0;
  502.                                         aNode := 0;
  503.                                         aSocket := 0;
  504.                                     end;
  505.                             end;
  506.  
  507.                         err := POpenATPSkt(@localATPPb, SYNC);
  508.                         if err = noErr then
  509.                             begin
  510.                                 UserSkt := localATPPb.atpSocket; {Save the socket #}
  511.         {Try to register the user on the network}
  512.                                 NBPSetEntity(@UserNTT, theString, USERTYPE, ANYZONE);
  513.                                 NBPSetNTE(@NBPsNTE, UserNTT.objStr, USERTYPE, ANYZONE, UserSkt); {Set up the nte that NBP wants}
  514.  
  515.                                 with localMPPPb do
  516.                                     begin
  517.                                         ioCompletion := nil;
  518.                                         interval := 3;
  519.                                         count := 3;
  520.                                         entityPtr := @NBPsNTE;
  521.                                         verifyFlag := DOVERIFY; {Make sure we register with a unique name}
  522.                                     end;
  523.  
  524.                                 err := PRegisterName(@localMPPPb, SYNC);
  525.                                 if err = noErr then
  526.                                     begin
  527.             {We registered successfully!}
  528.                                         UserRegistered := HooksRegistered; {Let the hook code do its magic}
  529.  
  530. {$IFC TALK_DEBUG }
  531.             {Enable self sending if the new calls exist}
  532.                                         if NewCallsExist then
  533.                                             begin
  534.                                                 localMPPPb.newSelfFlag := SENDSELF;
  535.                                                 err := PSetSelfSend(@localMPPPb, SYNC);
  536.                                                 if err = noErr then
  537.                                                     begin
  538.                                                         OldSelfFlag := localMPPPb.oldSelfFlag; {Save the old self flag state}
  539.                                                         SelfSendOn := T; {Mark our selfsend flag as on}
  540.                                                     end
  541.                                                 else
  542.                                                     SelfSendOn := F; {We failed, mark our selfsend flag as off}
  543.                                             end
  544.                                         else
  545.                                             SelfSendOn := F; {Mark our selfsend flag as off}
  546. {$ENDC}
  547.                                     end
  548.                                 else
  549.                                     begin
  550.             {PRegisterName failed}
  551.             {Close the UserSkt}
  552.                                         localATPPb.atpSocket := UserSkt;
  553.                                         err := PCloseATPSkt(@localATPPb, SYNC);
  554.                                     end;
  555.                             end;
  556.                     end
  557.                 else
  558.         {User didn't enter a valid string}
  559.                     goto 100;
  560.             end;
  561.  
  562.     {Close the dialog and return the result}
  563.         CloseDialog(theDialog);
  564.         SetPort(oldPort);
  565.     end;
  566.  
  567.  
  568.     function AppleTalkOK: Boolean;
  569.     {This proc makes sure we're running on at least a 512KE}
  570.     {, it returns T if so and checks to see if the new calls exist}
  571.         var
  572.             err: OSErr;
  573.             theWorld: SysEnvRec;
  574.     begin
  575.     {Assume we failed}
  576.         AppleTalkOK := F;
  577.  
  578.         err := MPPOpen; {Open AppleTalk}
  579.         if err = noErr then
  580.             begin
  581.                 err := SysEnvirons(1, theWorld);
  582.                 if err = noErr then
  583.                     begin
  584.                         with theWorld do
  585.                             begin
  586.                                 if machineType >= env512KE then
  587.                                     begin
  588.             {We've got at least a 512KE}
  589.                                         if atDrvrVersNum >= XNCVERSION then
  590.             {We've got the new calls}
  591.                                             NewCallsExist := T;
  592.                                         AppleTalkOK := UserRegistered; {Let the user try to register}
  593.                                     end;
  594.                             end;
  595.                     end;
  596.             end;
  597.     end;
  598.  
  599.  
  600.     procedure AppleTalkCallChecks;
  601.     {This proc checks to see if any of ASYNC calls have finished}
  602.         var
  603.             oldPort: GrafPtr;
  604.     begin
  605.         with LookUpNamePb do
  606.             begin
  607.                 if CallDone <> 0 then
  608.                     begin
  609.                         PbInUse := F;
  610.                         CallDone := 0;
  611.                         GetPort(oldPort);
  612.                         SetPort(UserWindow);
  613.                         UpdateNameList;
  614.                         LookUpString := 'done';
  615.                         DrawLookUpString;
  616.                         SetPort(oldPort);
  617.                     end;
  618.             end;
  619.  
  620.     {Allow any AppleTalk call checks in the Hooks unit}
  621.         HooksAppleTalkCallChecks;
  622.     end;
  623.  
  624.  
  625.     procedure CloseUpAppleTalk;
  626.     {This proc closes up the apps AppleTalk socket and lets the hook}
  627.     {code cleanup anything it did with AppleTalk}
  628.         var
  629.             localATPPb: ATPParamBlock;
  630.             localMPPPb: MPPParamBlock;
  631.             err: OSErr;
  632.     begin
  633.     {A LookUp call may not have finished, if the new calls exist}
  634.     {then KillNBP it, if not then we must wait till it finishes.}
  635.         with LookUpNamePb do
  636.             begin
  637.                 if PbInUse then
  638.                     begin
  639.         {There is a LookUpName in progress}
  640.                         if NewCallsExist then
  641.                             begin
  642.         {We've got the new calls so we can kill it}
  643.                                 with localMPPPb do
  644.                                     begin
  645.                                         ioCompletion := nil;
  646.                                         nKillQEl := @LookUpNamePb.xMPPPb;
  647.                                     end;
  648.                                 err := PKillNBP(@localMPPPb, SYNC);
  649.                                 if err <> noErr then
  650.                                     begin
  651.         {We failed to KillNBP the LookUp so we'll just loop till the LookUp is done}
  652.         {NOTE that we test the CallDone field since its changed by the completion routine, NOT}
  653.         {the PbInUse field}
  654.                                         while LookUpNamePb.CallDone = 0 do
  655.                                             ;
  656.                                     end;
  657.                             end
  658.                         else
  659.         {The new calls dont exist so we'll just loop till the LookUp is done}
  660.         {NOTE that we test the CallDone field since its changed by the completion routine, NOT}
  661.         {the PbInUse field}
  662.                             while LookUpNamePb.CallDone = 0 do
  663.                                 ;
  664.                     end;
  665.             end;
  666.  
  667.  
  668.     {Allow the Hooks unit to closeup any AppleTalk calls it made}
  669.         HooksCloseUpAppleTalk;
  670.  
  671.     {Close the UserSkt}
  672.         localATPPb.atpSocket := UserSkt;
  673.         err := PCloseATPSkt(@localATPPb, SYNC);
  674.         if err <> noErr then
  675.             SysBeep(1);
  676.  
  677.     {Remove the users name from the network}
  678.         localMPPPb.entityPtr := @UserNTT;
  679.         err := PRemoveName(@localMPPPb, SYNC);
  680.         if err <> noErr then
  681.             SysBeep(1);
  682.  
  683. {$IFC TALK_DEBUG }
  684.     {Restore the SelfSendFlag to its former state}
  685.         if NewCallsExist then
  686.             begin
  687.                 if SelfSendOn then
  688.                     begin
  689.                         if OldSelfFlag = 0 then
  690.                             begin
  691.         {Turn it off if it wasn't on before}
  692.                                 localMPPPb.newSelfFlag := OldSelfFlag;
  693.                                 err := PSetSelfSend(@localMPPPb, SYNC);
  694.                             end;
  695.                     end;
  696.             end;
  697. {$ENDC}
  698.     end;
  699.  
  700.  
  701.     function AppleTalkGlobalsSetUp: Boolean;
  702.     {This proc inits any app AppleTalk globals}
  703.     begin
  704.     {Assume error}
  705.         AppleTalkGlobalsSetUp := F;
  706.  
  707.         with LookUpNamePb do
  708.             begin
  709.                 PbInUse := F;
  710.                 CallDone := 0;
  711.             end;
  712.  
  713.         ConfirmString := 'never done';
  714.         LookUpString := 'never done';
  715.  
  716.     {Allow setup of AppleTalk globals from the Hooks unit}
  717.         if HooksAppleTalkGlobalsSetUp then
  718.             AppleTalkGlobalsSetUp := T;
  719.     end;
  720.  
  721.  
  722.     procedure DoWNEs;
  723.     {Do a few WNEs to make sure our dialog comes up in front}
  724.         var
  725.             theResult: Boolean;
  726.     begin
  727.         theResult := WaitNextEvent(everyEvent, Evt, 0, nil);
  728.         theResult := WaitNextEvent(everyEvent, Evt, 0, nil);
  729.         theResult := WaitNextEvent(everyEvent, Evt, 0, nil);
  730.         theResult := WaitNextEvent(everyEvent, Evt, 0, nil);
  731.         theResult := WaitNextEvent(everyEvent, Evt, 0, nil);
  732.     end;
  733.  
  734.  
  735.     procedure DoAbout;
  736.     {This proc shows our About box}
  737.         var
  738.             theDialog: DialogPtr;
  739.             theDRec: DialogRecord;
  740.             oldPort: GrafPtr;
  741.             itemhit: Integer;
  742.     begin
  743.         GetPort(oldPort);
  744.  
  745.         theDialog := GetNewDialog(rABOUTDLOGID, @theDRec, WindowPtr(-1));
  746.         SetPort(theDialog);
  747.         ShowWindow(theDialog);
  748.  
  749.         repeat
  750.             ModalDialog(nil, itemHit)
  751.         until (itemHit = ok);
  752.  
  753.         CloseDialog(theDialog);
  754.  
  755.         SetPort(oldPort);
  756.     end;
  757.  
  758.  
  759.     procedure DoAppleMenu (item: Integer);
  760.     {This proc handles the Apple Menu}
  761.     begin
  762.         case item of
  763.             ABOUTITEM: 
  764.                 DoAbout;
  765.             otherwise
  766.         end;
  767.     end;
  768.  
  769.  
  770.     procedure DoFileMenu (item: Integer);
  771.     {This proc handles the File Menu}
  772.     begin
  773.         case item of
  774.             QUITITEM: 
  775.                 DoneFlag := T;
  776.             otherwise
  777.         end;
  778.     end;
  779.  
  780.  
  781.     procedure DoLookUp;
  782.     {This proc does an ASYNC LookUpName}
  783.         var
  784.             oldPort: GrafPtr;
  785.             err: OSErr;
  786.     begin
  787.         with LookUpNamePb do
  788.             begin
  789.                 if PbInUse = F then
  790.                     begin
  791.         {If we're not already doing one}
  792.                         NBPSetEntity(@LookUpNTT, ANYOJB, USERTYPE, ANYZONE); {Setup who to look for}
  793.  
  794.                         CallDone := 0;
  795.  
  796.                         with xMPPPb do
  797.                             begin
  798.                                 ioCompletion := @XCompletionRoutine;
  799. {$IFC TALK_DEBUG }
  800.                                 interval := 2;
  801.                                 count := 3;
  802. {$ELSC}
  803.                                 interval := 6;
  804.                                 count := 5;
  805. {$ENDC}
  806.                                 entityPtr := @LookUpNTT;
  807.                                 retBuffPtr := @LookUpBuffer;
  808.                                 retBuffSize := sizeof(LookUpBuffer);
  809.                                 maxToGet := MAXTOLOOKUP;
  810.                             end;
  811.  
  812.                         err := PLookUpName(@xMPPPb, ASYNC);
  813.         {Show the LookUps progress}
  814.                         GetPort(oldPort);
  815.                         SetPort(UserWindow);
  816.                         if err = noErr then
  817.                             begin
  818.                                 PbInUse := T;
  819.                                 LookUpString := 'in progress';
  820.                             end
  821.                         else
  822.                             LookUpString := 'error';
  823.                         DrawLookUpString;
  824.                         SetPort(oldPort);
  825.                     end;
  826.             end;
  827.     end;
  828.  
  829.  
  830.     procedure DoConfirm;
  831.     {This proc does a SYNC ConfirmName}
  832.         var
  833.             theAddress: AddrBlock;
  834.             nameIsSelected: Boolean;
  835.             theCell: Cell;
  836.             extractedNTT, ntt2Confirm: EntityName;
  837.             oldPort: GrafPtr;
  838.             err: OSErr;
  839.     begin
  840.         if LookUpNamePb.PbInUse then
  841.             begin
  842.     {Dont try to ConfirmName while a LookUp is in progress}
  843.                 GetPort(oldPort);
  844.                 SetPort(UserWindow);
  845.                 ConfirmString := 'LookUp in progress';
  846.                 DrawConfirmString;
  847.                 SetPort(oldPort);
  848.             end
  849.         else
  850.             begin
  851.                 theCell.h := 0;
  852.                 theCell.v := 0;
  853.                 nameIsSelected := LGetSelect(T, theCell, NameListHdl); {Get the selected list item}
  854.  
  855.                 if nameIsSelected then
  856.                     begin
  857.         {Only do a Confirm if an item in the list is selected}
  858.                         theCell.v := theCell.v + 1;
  859.                         err := NBPExtract(@LookUpBuffer, NameListLength, theCell.v, extractedNTT, theAddress); {Get the address}
  860.                         if err = noErr then
  861.                             begin
  862.                                 NBPSetEntity(@ntt2Confirm, extractedNTT.objStr, extractedNTT.typeStr, extractedNTT.zoneStr);
  863.  
  864.                                 err := NTTExists(ntt2Confirm, theAddress); {Check if the NTT exists}
  865.         {Show the result of the ConfirmName}
  866.                                 GetPort(oldPort);
  867.                                 SetPort(UserWindow);
  868.                                 if err = noErr then
  869.                                     ConfirmString := 'confirmed'
  870.                                 else
  871.                                     begin
  872.                                         case err of
  873.                                             nbpNoConfirm: 
  874.                                                 ConfirmString := 'can''t confirm ';
  875.                                             nbpConfDiff: 
  876.                                                 ConfirmString := 'moved';
  877.                                             otherwise
  878.                                                 ConfirmString := 'error';
  879.                                         end;
  880.                                     end;
  881.                                 DrawConfirmString;
  882.                                 SetPort(oldPort);
  883.                             end;
  884.                     end;
  885.             end;
  886.     end;
  887.  
  888.  
  889.     procedure DoSendRequest;
  890.     {This is the generic codes response to choosing 'Send'}
  891.     begin
  892.         SysBeep(1);
  893.     end;
  894.  
  895.  
  896.     procedure DoSpecialMenu (item: Integer);
  897.     {This proc handles the Special Menu}
  898.     begin
  899.         case item of
  900.             LOOKUPITEM: 
  901.                 DoLookUp;
  902.             CONFIRMITEM: 
  903.                 DoConfirm;
  904.             SENDITEM: 
  905.                 DoSendRequest;
  906.             otherwise
  907.         end;
  908.     end;
  909.  
  910.  
  911.     procedure DoMenu (menuChoice: LongInt);
  912.     {This proc handles menu selections}
  913.         var
  914.             theItem, theMenu: Integer;
  915.     begin
  916.         theItem := LoWord(menuChoice);
  917.         theMenu := HiWord(menuChoice);
  918.  
  919.         if HookedMenuChoice(theMenu, theItem) = F then
  920.             begin
  921.     {Hook code didn't handle the menu choice so the generic code must}
  922.                 case theMenu of
  923.                     APPLEMENUID: 
  924.                         DoAppleMenu(theItem);
  925.                     FILEMENUID: 
  926.                         DoFileMenu(theItem);
  927.                     SPECIALMENUID: 
  928.                         DoSpecialMenu(theItem);
  929.                     otherwise
  930.                 end;
  931.             end;
  932.  
  933.         HiliteMenu(0);
  934.     end;
  935.  
  936.  
  937.     procedure DoKDown;
  938.     {This code handles keydowns}
  939.         type
  940.             Trick = packed record
  941.                     case Boolean of
  942.                         TRUE: (
  943.                                 long: Longint
  944.                         );
  945.                         FALSE: (
  946.                                 chr3, chr2, chr1, chr0: Char
  947.                         )
  948.                 end;
  949.         var
  950.             charCode: Char;
  951.             trickVar: Trick;
  952.     begin
  953.         trickVar.long := Evt.message;
  954.         charCode := trickVar.chr0;
  955. {IF BitAnd(Evt.modifiers, CmdKey) = CmdKey THEN}
  956.         if BAnd(CmdKey, Evt.modifiers) <> 0 then
  957.             DoMenu(MenuKey(charCode));
  958.     end;
  959.  
  960.  
  961.     procedure DoContentHit;
  962.     {This code handles hits in the apps windows}
  963.         var
  964.             clickResult: Boolean;
  965.             localPt: Point;
  966.     begin
  967.         if WhichWindow <> FrontWindow then
  968.             SelectWindow(WhichWindow)
  969.         else
  970.             begin
  971.                 localPt := Evt.where;
  972.                 SetPort(WhichWindow);
  973.                 if WhichWindow = UserWindow then
  974.                     begin
  975.                         if UserWindowProcsChanged then
  976.                             HooksUserWindowDoContentHit {Let the hook code do its magic}
  977.                         else
  978.                             begin
  979.                                 GlobalToLocal(localPt);
  980.                                 if PtinRect(localPt, ListFrameRect) then
  981.                                     clickResult := LClick(localPt, Evt.modifiers, NameListHdl);
  982.                             end;
  983.                     end
  984.                 else
  985.         {A hook window was hit, let it handle it}
  986.                     DoHooksWindowContentHit;
  987.             end;
  988.     end;
  989.  
  990.  
  991.     procedure DoMDown;
  992.     {This code handles mouse down events}
  993.         var
  994.             theResult: Integer;
  995.     begin
  996.         theResult := FindWindow(Evt.where, WhichWindow);
  997.         case theResult of
  998.             inDrag: 
  999.                 DoDrag;
  1000.             inMenuBar: 
  1001.                 DoMenu(MenuSelect(Evt.where));
  1002.             inContent: 
  1003.                 DoContentHit;
  1004.             otherwise
  1005.         end;
  1006.     end;
  1007.  
  1008.  
  1009.     procedure MainLoop;
  1010.     {This is the apps event loop}
  1011.         var
  1012.             theResult: Boolean;
  1013.     begin
  1014.         while DoneFlag = F do
  1015.             begin
  1016.                 theResult := WaitNextEvent(everyEvent, Evt, SleepTime, nil);
  1017.                 AppleTalkCallChecks; {Check to see if any ASYNC calls completed}
  1018.                 if theResult then
  1019.                     begin
  1020.         {Handle any event}
  1021.                         case Evt.what of
  1022.                             keyDown: 
  1023.                                 DoKDown;
  1024.                             mouseDown: 
  1025.                                 DoMDown;
  1026.                             activateEvt: 
  1027.                                 DoActivate;
  1028.                             updateEvt: 
  1029.                                 DoUpdate;
  1030.                             MFEVENT: 
  1031.                                 DoMFEvent;
  1032.                             otherwise
  1033.                         end;
  1034.                     end;
  1035.             end;
  1036.     end;
  1037.  
  1038.  
  1039. {$I-}
  1040.  {We do our own inits}
  1041. begin
  1042.     SetUpToolbox;
  1043.     SetUpGlobals;
  1044.     DoWNEs;
  1045.  
  1046.     if AppleTalkOK then
  1047.         begin
  1048.             SetUpMenus;
  1049.  
  1050.             if GotWindows then
  1051.                 begin
  1052.  
  1053.                     if AppleTalkGlobalsSetUp then
  1054.                         begin
  1055.  
  1056.                             MainLoop;
  1057.  
  1058.                             CloseWindows;
  1059.                         end;
  1060.                 end;
  1061.  
  1062.             CloseUpAppleTalk;
  1063.         end;
  1064.  
  1065.     ExitToShell;
  1066. end.